/*****************************************************************************
 *
 * HUSONG PROPRIETARY INFORMATION
 *
 * The information contained herein is proprietary to HUSONG
 * and shall not be reproduced or disclosed in whole or in part
 * or used for any design or manufacture
 * without direct written authorization from HUSONG.
 *
 * Copyright (c) 2015 by HUSONG. All rights reserved.
 *
 *****************************************************************************/
package me.send.broker.mapper;

import java.util.List;
import java.util.Map;

import me.send.broker.entity.BatchWithdrawOrder;
import me.send.broker.entity.BrokerWalletLog;
import me.send.broker.entity.WithdrawOrder;
import me.send.broker.mapper.provider.WalletProvider;
import me.send.broker.pojo.WithdrawRecord;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.Update;
import org.apache.ibatis.annotations.UpdateProvider;

/**
 * @author maxmin
 *
 * @date 2015年8月3日 下午4:08:28
 */
public abstract interface WalletMapper {
    /**
     * 给还未创建钱包记录的经纪人创建钱包
     * @param popid 经纪人id
     */
    @Insert("insert into broker_wallet values (#{popid},0,#{date},1,0,0)")
    public abstract void addBrokerWallet(Map<String, Object> param);
    
    /**
     * 经纪人钱包发生变动时添加记录
     * @param param
     */
    @Insert("insert into broker_wallet_log(changeDesc,orderId,changeTime,brokerId,purchaseAmount,tipAmount,orderNo) values (#{changeDesc},#{orderId},#{changeTime},#{brokerId},#{purchaseAmount},#{tipAmount},#{orderNo})")
    public abstract void addBrokerWalletLog(Map<String, Object> param);
    
    /**
     * 给经纪人付款
     * @param param
     */
    @Update("update broker_wallet set purchaseBalance=purchaseBalance+#{purchaseAmount},tipBalance=tipBalance+#{tipAmount} where popid=#{brokerid}")
    public abstract void payToBroker(Map<String, Object> param);
    
    /**
     * 对经纪人钱包进行冻结
     * @param param
     */
    @Update("update broker_wallet set frozenMoney=frozenMoney+#{dPurchase}+#{dTip},purchaseBalance=purchaseBalance-#{dPurchase},tipBalance=tipBalance-#{dTip} where popid=#{popid}")
    public abstract void frozenBrokerWallet(Map<String, Object> param);
    
    /**
     * 获取经纪人的钱包余额信息
     * @param popid 经纪人id
     * @return 经纪人代购金额，小费，可取余额
     */
    @Select(value = "select purchaseBalance,tipBalance,purchaseBalance+tipBalance total from broker_wallet where popid=#{popid}")
    public abstract Map<String, Object> getBalance(int popid);
    
    @Insert(value = "insert into withdraw_order(brokerId,withdrawType,withdrawAccountNo,createTime,withdrawAmount,status,withdrawOrderNo,brokerName,serviceAmount) values "
		    + "(#{popid},#{type},#{accountNumber},#{createTime},#{num},#{status},#{withdrawOrderNo},#{brokerName},#{serviceAmount})")
    public abstract void buildRecord(WithdrawRecord wr);
    
    /**
     * 获取经纪人端钱包的小费记录
     * @param popid 经纪人id
     * @return
     */
    @SelectProvider(method = "chargeInDetails",
		    type = WalletProvider.class)
    public abstract List<Map<String, Object>> chargeInDetails(
	    Map<String, Object> param);
    
    /**
     * 获取经纪人端钱包的小费总额
     * @param popid 经纪人id
     * @return
     */
    @Select("select sum(tipAmount) total from broker_wallet_log where brokerId=#{popid} and purchaseAmount>=0 and tipAmount>=0")
    public abstract Object chargeInTotal(int popid);
    
    /**
     * 获取经纪人端钱包的记录页数
     * @param param
     * @return
     */
    @SelectProvider(method = "chargeInPage",
		    type = WalletProvider.class)
    public abstract Object chargeInPage(Map<String, Object> param);
    
    /**
     * 获取经纪人端钱包的代购总额明细
     * @param popid 经纪人id
     * @return
     */
    @SelectProvider(method = "buyDetails", type = WalletProvider.class)
    public abstract List<Map<String, Object>> buyDetails(
	    Map<String, Object> param);
    
    /**
     * 获取经纪人端钱包的代购总额
     * @param popid 经纪人id
     * @return
     */
    @Select("select sum(purchaseAmount) total from broker_wallet_log where brokerId=#{popid} and purchaseAmount>0")
    public abstract Object buyTotal(int popid);
    
    /**
     * 获取经纪人端钱包的记录页数
     * @param param
     * @return
     */
    @SelectProvider(method = "buyPage", type = WalletProvider.class)
    public abstract Object buyPage(Map<String, Object> param);
    
    /**
     * 获取经纪人端钱包的所有可取余额明细
     * @param popid 经纪人id
     * @return
     */
    @SelectProvider(method = "allDetails", type = WalletProvider.class)
    public abstract List<Map<String, Object>> allDetails(
	    Map<String, Object> param);
    
    @SelectProvider(method = "allPage", type = WalletProvider.class)
    public abstract Object allPage(Map<String, Object> param);
    
    /**
     * 获取经纪人正在提现的金额总额
     * @param popid
     * @return
     */
    @Select("select sum(withdrawAmount) from withdraw_order where brokerId=#{popid} and (status=0 or status=1)")
    public abstract Object inWithdraw(int popid);
    
    /**
     * 获取经纪人当日的成交额
     * @param param {popid:经纪人id,date:今日日期}
     * @return
     */
    @Select("select sum(purchaseAmount+tipAmount) total from broker_wallet_log where brokerId=#{popid} and purchaseAmount>=0 and tipAmount>=0 and changeTime like #{date}")
    public abstract Object todayTotal(Map<String, Object> param);
    
    /**
     * 获取经纪人端钱包的所有提现记录
     * @param popid 经纪人id
     * @return
     */
    @SelectProvider(method = "withdrawDetails",
		    type = WalletProvider.class)
    public abstract List<Map<String, Object>> withdrawDetails(
	    Map<String, Object> param);
    
    /**
     * 获取经纪人端钱包的记录页数
     * @param param
     * @return
     */
    @SelectProvider(method = "withdrawPage",
		    type = WalletProvider.class)
    public abstract Object withdrawPage(Map<String, Object> param);
    
    /**
     * 获取用户的钱包余额
     * @param userid 用户id
     * @return
     */
    @Select("select balance from user_wallet where userId=#{userid}")
    public abstract Object user_balance(int userid);
    
    /**
     * 为新用户增加一条钱包记录
     * @param userid
     */
    @Insert("insert into user_wallet(createTime,userId) values(#{createTime},#{userId})")
    public abstract void addUserWallet(Map<String, Object> param);
    
    /**
     * 用户在对钱包进行充值或者使用钱包进行支付时修改钱包余额
     * @param param {userid:userid,amount:+表示充值等收入,-表示支付等支出}
     */
    @Update("update user_wallet set balance=balance+#{amount} where userId=#{userid}")
    public abstract void updateUserWallet(Map<String, Object> param);
    
    /**
     * 在用户钱包发生金额变动，即发生充值或者支付行为时，为用户行为生成变更记录
     * @param param {amount:金额,changeTime:交易时间,changeType:交易类型，0收入，1支出
     * orderId:关联的支付宝或者呼单号，userId:用户id，changeDesc:交易描述}
     */
    @Insert("insert into user_wallet_log(amount,changeTime,changeType,changeDesc,orderId,userId) values(#{amount},#{changeTime},#{changeType},#{changeDesc},#{orderId},#{userid})")
    public abstract void buildUserRecord(Map<String, Object> param);
    
    /**
     * 用户发送充值行为或者使用第三方进行支付时生成支付订单
     * @param param {amount:金额,createTime:创建时间,payType:付款类型0支付宝1微信,
     * payOrderNo:流水号,userId:用户id}
     */
    @Insert("insert into pay_order(amount,createTime,payType,payOrderNo,userId,status,orderId) values(#{amount},#{createTime},#{payType},#{payOrderNo},#{userId},0,#{orderId})")
    public abstract void builePayRecord(Map<String, Object> param);
    
    /**
     * 根据用户的支付订单号查询该订单详细信息
     * @param payOrderNo 唯一订单号
     * @return 支付订单详细信息
     */
    @Select("select * from pay_order where payOrderNo=#{payOrderNo}")
    public abstract Map<String,Object> userOrderStatus(String payOrderNo);
    
    /**
     * 用户支付成功，更新支付订单的支付状态为1
     * @param payOrderNo 唯一订单号
     */
    @Update("update pay_order set status=1 where payOrderNo=#{payOrderNo}")
    public abstract void updateUserOrderStatus(String payOrderNo);
    /**
     * 根据创建时间查询<=传入时间的提现订单数量
     * @param time
     * @return
     */
    @Select("select count(1) from withdraw_order where createTime <= #{time} and batchOrderNo is null and status =1 ")
    public abstract int queryWithdrawOrderCount(String time);
   
    @Select("select * from withdraw_order where createTime <= #{time} and batchOrderNo is null and status =1 order by withdrawOrderId limit #{size}")
    public abstract List<Map<String, Object>> queryWithdrawOrders(Map<String,Object> param);
    
    @Select("select withdrawOrderId from withdraw_order where createTime <= #{time} and batchOrderNo is null and status =1 order by withdrawOrderId limit 100")
    public abstract List<Integer> queryWithdrawOrderIds(String time);
    
    @UpdateProvider(type = WalletProvider.class, method = "batchUpdateWithdrawOrder")
    public abstract void batchUpdateWithdrawOrder(Map<String,Object> param);
    
    @Insert("insert into batch_withdraw_order(batchOrderNo,batchFee,batchNum,createTime,status,latestTime) values (#{batchOrderNo},#{batchFee},#{batchNum},#{createTime},0,#{latestTime})")
    public abstract void insertBatchWithdrawOrder(Map<String, Object> param);
    
    @Select("select * from withdraw_order o where o.batchOrderNo = #{batchOrderNo} and o.status=1 and withdrawType =0")
    public abstract List<WithdrawOrder> queryAliWithdrawOrderByBatchOrderNo(String batchOrderNo);
    
    @Select("select * from batch_withdraw_order o where o.batchOrderNo = #{batchOrderNo} ")
    public abstract BatchWithdrawOrder queryBatchWithdrawOrderByOrderNo(String batchOrderNo);
    
    @UpdateProvider(type = WalletProvider.class, method = "batchUpdateAliWithdrawOrder")
    public abstract void batchUpdateAliWithdrawOrder(Map<String,Object> param);
    
    @UpdateProvider(type = WalletProvider.class, method = "batchDeductBrokerWallet")
    public abstract void batchDeductBrokerWallet(Map<String, Object> param);
    
    @Update("update batch_withdraw_order o set o.status = #{status} ,o.finishTime = #{finishTime} ,o.notifyId = #{notifyId} where batchOrderId = #{batchOrderId}")
    public abstract void updateBatchWithdrawOrder(Map<String, Object> param);
    
    @SelectProvider(type = WalletProvider.class, method = "queryBrokerWalletLogsByOrderNo")
    public abstract List<BrokerWalletLog> queryBrokerWalletLogsByOrderNo(Map<String,Object> queryMap);
    
    @UpdateProvider(type = WalletProvider.class, method = "batchUpdateBrokerWallet")
    public abstract void batchUpdateBrokerWallet(Map<String,Object> param);
    
    @UpdateProvider(type = WalletProvider.class, method = "batchInsertBrokerWalletLog")
    public abstract void batchInsertBrokerWalletLog(Map<String,Object> param);
}
